
. .\PSHamcrest.ps1

Function Test_ExecuteTestFunctions_PassingTest_PassesTest
{
    # Arrange.
    Function Test_One
    {
        AssertThat 1 (EqualTo 1)
    }

    # Act.
    $results = ExecuteTestFunctions "Test_One"

    # Assert.
    AssertThat $results[0].Passed (IsTrue)
}

Function Test_ExecuteTestFunctions_FailingTest_FailsTest
{
    # Arrange.
    Function Test_One
    {
        AssertThat 1 (EqualTo 2)
    }

    # Act.
    $testResults = ExecuteTestFunctions "Test_One"

    # Assert.
    AssertThat $testResults[0].TestName (EqualTo "One")
    AssertThat $testResults[0].Passed (IsFalse)
    AssertThat $testResults[0].ExceptionMessage (StartsWith "'1' should be equal to '2'")
}

Function Test_ExecuteTests_3Tests_CallsEachTest
{
    # Arrange.
    $mock1 = ""
    $mock2 = ""
    $mock3 = ""
    $mock4 = ""
    Function Test_One { Set-Variable -Name mock1 -Value "Test_One" -Scope 2 }
    Function Test_Two { Set-Variable -Name mock2 -Value "Test_Two" -Scope 2 }
    Function Test_Three {}
    Function Test_Four { Set-Variable -Name mock4 -Value "Test_Four" -Scope 2 }
    $testFunctionNames = "Test_One", "Test_Two", "Test_Three", "Test_Four"

    # Act.
    $results = ExecuteTestFunctions $testFunctionNames

    # Assert.
    AssertThat $mock1 (EqualTo "Test_One")
    AssertThat $mock2 (EqualTo "Test_Two")
    AssertThat $mock3 (EqualTo "")
    AssertThat $mock4 (EqualTo "Test_Four")
}

Function Test_NewMatcher_MakeNewMatcher_DefaultMatcher
{
    # Arrange, Act.
    $matcher = New-Matcher

    # Assert.
    AssertThat $matcher.Description (EqualTo "")
    AssertThat $matcher.Value (EqualTo "")
}

# Anything

Function Test_Anything_Anything_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: Tautological match")
    }
}

# Contains

Function Test_Contains_MatchingSubstring_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "aoeu" (Contains "oe")
}

Function Test_Contains_NoMatchingSubstring_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat "aoeu" (Contains "2134")

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'aoeu' should contain '2134'")
    }
}

Function Test_NotContains_NoMatchingSubstring_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "aoeu" (Not (Contains "234"))
}

Function Test_NotContains_MatchingSubstring_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat "aoeu" (Not (Contains "oe"))

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'aoeu' should not contain 'oe'")
    }
}

# EndsWith

Function Test_EndsWith_CorrectSuffix_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "aoeu" (EndsWith "eu")
}

Function Test_EndsWith_IncorrectSuffix_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat "aoeu" (EndsWith "oe")

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'aoeu' should end with 'oe'")
    }
}

Function Test_NotEndsWith_IncorrectSuffix_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "aoeu" (Not (EndsWith "oe"))
}

Function Test_NotEndsWith_CorrectSuffix_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat "aoeu" (Not (EndsWith "eu"))

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'aoeu' should not end with 'eu'")
    }
}

# EqualTo

Function Test_EqualTo_UnequalInts_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat 5 (EqualTo 4)
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: '5' should be equal to '4'")
    }
}

Function Test_EqualTo_EqualStrings_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "aoeu" (EqualTo "aoeu")
}

Function Test_NotEqualTo_EqualInts_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat 5 (Not (EqualTo 5))

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: '5' should not be equal to '5'")
    }
}

Function Test_NotEqualTo_UnequalStrings_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "aoeu" (Not (EqualTo "aoeu1"))
}

# GreaterThan

Function Test_GreaterThan_IsGreater_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat 2 (GreaterThan 1)
}

Function Test_GreaterThan_IsLessThanOrEqualTo_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat 2 (GreaterThan 3)

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: '2' should be greater than '3'")
    }
}

Function Test_NotGreaterThan_IsLessThanOrEqual_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat 1 (Not (GreaterThan 2))
}

Function Test_NotGreaterThan_IsGreaterThan_ExceptionThrown
{
    Try
    {
        # Arrange. # Act.
        AssertThat 3 (Not(GreaterThan 2))

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: '3' should not be greater than '2'")
    }
}

# IsFalse

Function Test_IsFalse_True_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat $true (IsFalse)

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'True' should be FALSE")
    }
}

Function Test_IsFalse_False_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat $false (IsFalse)
}

Function Test_NotIsFalse_False_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat $false (Not (IsFalse))

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'False' should be TRUE")
    }
}

Function Test_NotIsFalse_True_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat $true (Not (IsFalse))
}

# IsNull

Function Test_IsNull_NotNull_ExceptionThrown
{
    Try
    {
        AssertThat "not null" (IsNull)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'not null' should be NULL")
    }
}

Function Test_IsNull_Null_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat $null (IsNull)
}

Function Test_NotIsNull_Null_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat $null (Not (IsNull))
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: `$null should not be NULL")
    }
}

Function Test_NotIsNull_NonNull_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "not null" (Not (IsNull))
}

# IsTrue

Function Test_IsTrue_False_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat $false (IsTrue)

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'False' should be TRUE")
    }
}

Function Test_IsTrue_True_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat $true (IsTrue)
}

Function Test_NotIsTrue_True_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat $true (Not (IsTrue))

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'True' should be FALSE")
    }
}

Function Test_NotIsTrue_False_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat $false (Not (IsTrue))
}

# StartsWith

Function Test_StartsWith_CorrectPrefix_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "aoeu" (StartsWith "ao")
}

Function Test_StartsWith_IncorrectPrefix_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat "aoeu" (StartsWith "oe")

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'aoeu' should start with 'oe'")
    }
}

Function Test_NotStartsWith_IncorrectPrefix_NoOutput
{
    # Arrange, Act, Assert.
    AssertThat "aoeu" (Not (StartsWith "oe"))
}

Function Test_NotStartsWith_CorrectPrefix_ExceptionThrown
{
    Try
    {
        # Arrange, Act.
        AssertThat "aoeu" (Not (StartsWith "ao"))

        # Force exception in case it doesn't throw one.
        AssertThat "match" (Anything)
    }
    Catch
    {
        # Assert.
        AssertThat $_.Exception.ToString() (StartsWith "System.Management.Automation.RuntimeException: 'aoeu' should not start with 'ao'")
    }
}

ExecuteTests $args[0]

# vim: ft=ps1
